﻿using LiteDB;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace LiteDb
{
    public class Group
    {
        public const string CollectionName = nameof(Group);
        
        [BsonId(true)] // 启用自动递增的整数ID
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public BsonDocument Extra { get; set; } = new BsonDocument();
    }

    public class GroupDevice
    {
        public const string CollectionName = nameof(GroupDevice);
        
        [BsonId(true)] // 启用自动递增的整数ID
        public int Id { get; set; }
        public int GroupId { get; set; }
        public string Name { get; set; } = string.Empty;
        public string GatewayType { get; set; } = string.Empty;
        public bool AllowDeviceRename { get; set; }
        public bool AllowVariableRename { get; set; }
        public HardwareInfo HardwareInfo { get; set; } = new HardwareInfo();
    }

    public class HardwareInfo
    {
        public string UpdateMode { get; set; } = string.Empty;
        public int IoCount { get; set; }
        public int SerialPortCount { get; set; }
        public int DeviceCount { get; set; }
        public int VariableCount { get; set; }
        public int ControlTopicCount { get; set; }
        public int UploadTopicCount { get; set; }
        public int MqttCount { get; set; }
        public string HardwareDescription { get; set; } = string.Empty;
    }

    public class GroupRepository
    {
        private readonly ILiteCollection<Group> _collection;
        private readonly ILiteCollection<GroupDevice> _deviceCollection;
        public const string DefaultGroupName = "默认分组";

        public GroupRepository(LiteDatabase db)
        {
            _collection = db.GetCollection<Group>(Group.CollectionName);
            _deviceCollection = db.GetCollection<GroupDevice>(GroupDevice.CollectionName);
            InitializeDefaultGroup();
        }

        private void InitializeDefaultGroup()
        {
            try
            {
                // 检查是否存在任何分组
                var defaultGroup = _collection.FindOne(x => x.Name == DefaultGroupName);
                
                // 如果默认分组不存在，创建它
                if (defaultGroup == null)
                {
                    var group = new Group
                    {
                        Name = DefaultGroupName,
                        Extra = new BsonDocument()
                    };
                    _collection.Insert(group);
                }
            }
            catch (Exception ex)
            {
                // 记录错误但不抛出异常，因为这是初始化过程
                Console.WriteLine($"初始化默认分组时出错: {ex.Message}");
            }
        }

        public object Insert(object param)
        {
            try
            {
                string name = param.ToString()!;
                
                // 检查是否已存在同名分组
                var existingGroup = _collection.FindOne(x => x.Name == name);
                if (existingGroup != null)
                {
                    return ApiResponse.Fail("插入失败: 分组名称已存在");
                }

                Group group = new Group
                {
                    Name = name,
                };
                var id = _collection.Insert(group);
                return ApiResponse.Success(id.AsInt32, "插入成功");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("插入失败: " + ex.Message);
            }
        }

        public object FindById(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                var result = _collection.FindById(id);
                if (result == null)
                    return ApiResponse.Fail("未找到数据", null, ApiResponseCode.NotFound);
                return ApiResponse.Success(result);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }

        public object FindAll(object? param = null)
        {
            try
            {
                var allGroups = _collection.FindAll().ToList();
                
                // 将默认分组移到最前面
                var orderedGroups = allGroups
                    .OrderByDescending(g => g.Name == DefaultGroupName) // 默认分组排在最前
                    .ThenBy(g => g.Id) // 其他分组按ID排序
                    .Select(g => new { id = g.Id, name = g.Name })
                    .ToList();

                return ApiResponse.Success(orderedGroups);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }

        public object Update(object param)
        {
            try
            {
                var jsonString = param.ToString()!;
                var jObject = JObject.Parse(jsonString);

                // 解析ID
                if (!jObject.TryGetValue("id", out var idToken) && !jObject.TryGetValue("Id", out idToken))
                {
                    return ApiResponse.Fail("更新失败: 缺少ID字段");
                }

                int id = idToken.Type == JTokenType.String ? 
                    int.Parse(idToken.ToString()) : 
                    idToken.Value<int>();

                // 获取现有记录
                var existingGroup = _collection.FindById(id);
                if (existingGroup == null)
                {
                    return ApiResponse.Fail("更新失败: 记录不存在");
                }

                // 更新字段
                string newName = existingGroup.Name; // 保持原有名称作为默认值
                if (jObject.TryGetValue("title", out var titleToken))
                {
                    newName = titleToken.ToString();
                }
                else if (jObject.TryGetValue("name", out var nameToken))
                {
                    newName = nameToken.ToString();
                }

                // 检查是否已存在同名分组（排除当前更新的记录）
                if (newName != existingGroup.Name)
                {
                    var duplicateGroup = _collection.FindOne(x => x.Name == newName && x.Id != id);
                    if (duplicateGroup != null)
                    {
                        return ApiResponse.Fail("更新失败: 分组名称已存在");
                    }
                }

                // 应用更新
                existingGroup.Name = newName;

                // 执行更新
                bool ok = _collection.Update(existingGroup);
                return ok ? ApiResponse.Success(ok, "更新成功") : ApiResponse.Fail("更新失败", ok);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("更新异常: " + ex.Message);
            }
        }

        public object Delete(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                
                // 先检查分组是否存在
                var group = _collection.FindById(id);
                if (group == null)
                {
                    return ApiResponse.Fail("删除失败: 分组不存在");
                }
                
                // 保护默认分组不被删除
                if (group.Name == DefaultGroupName)
                {
                    return ApiResponse.Fail("删除失败: 默认分组不能被删除");
                }
                
                // 获取该分组下的设备数量
                var deviceCount = _deviceCollection.Count(d => d.GroupId == id);
                
                // 批量删除设备
                if (deviceCount > 0)
                {
                    _deviceCollection.DeleteMany(d => d.GroupId == id);
                }
                
                // 删除分组
                bool ok = _collection.Delete(id);
                
                if (ok)
                {
                    return ApiResponse.Success(ok, $"删除成功，同时删除了 {deviceCount} 个设备");
                }
                else
                {
                    return ApiResponse.Fail("删除失败: 分组删除失败");
                }
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("删除异常: " + ex.Message);
            }
        }

        public object GetByGroupId(object param)
        {
            try
            {
                int groupId = Convert.ToInt32(param);
                var list = _collection.FindAll().Where(g => g.Id == groupId).ToList();
                return ApiResponse.Success(list);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }

        public object GetGroupTreeWithDevices()
        {
            try
            {
                var allGroups = _collection.FindAll().ToList();
                var allDevices = _deviceCollection.FindAll().ToList();

                // 构建分组树
                var groupTree = allGroups
                    .OrderByDescending(g => g.Name == DefaultGroupName) // 默认分组排在最前
                    .ThenBy(g => g.Id)
                    .Select(g => new
                    {
                        id = g.Id,
                        title = g.Name,  // 改为 title
                        devices = allDevices
                            .Where(d => d.GroupId == g.Id)
                            .Select(d => new
                            {
                                id = d.Id,
                                name = d.Name,
                                gatewayType = d.GatewayType,
                                allowDeviceRename = d.AllowDeviceRename,
                                allowVariableRename = d.AllowVariableRename
                            })
                            .ToList()
                    })
                    .ToList();

                return ApiResponse.Success(groupTree);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("获取分组树失败: " + ex.Message);
            }
        }
    }

    public class GroupDeviceRepository
    {
        private readonly ILiteCollection<GroupDevice> _collection;

        public GroupDeviceRepository(LiteDatabase db)
        {
            _collection = db.GetCollection<GroupDevice>(GroupDevice.CollectionName);
        }

        public object Insert(object param)
        {
            try
            {
                var jsonString = param.ToString()!;
                var jObject = JObject.Parse(jsonString);

                // 创建新的GroupDevice对象
                var groupDevice = new GroupDevice();

                // 设置各个字段
                if (jObject.TryGetValue("groupId", out var groupIdToken))
                {
                    groupDevice.GroupId = groupIdToken.Value<int>();
                }
                if (jObject.TryGetValue("name", out var nameToken))
                {
                    groupDevice.Name = nameToken.ToString();
                }
                if (jObject.TryGetValue("gatewayType", out var gatewayTypeToken))
                {
                    groupDevice.GatewayType = gatewayTypeToken.ToString();
                }
                if (jObject.TryGetValue("allowDeviceRename", out var allowDeviceRenameToken))
                {
                    groupDevice.AllowDeviceRename = allowDeviceRenameToken.Value<bool>();
                }
                if (jObject.TryGetValue("allowVariableRename", out var allowVariableRenameToken))
                {
                    groupDevice.AllowVariableRename = allowVariableRenameToken.Value<bool>();
                }
                if (jObject.TryGetValue("hardwareInfo", out var hardwareInfoToken))
                {
                    var hardwareInfo = hardwareInfoToken.ToObject<HardwareInfo>();
                    if (hardwareInfo != null)
                    {
                        groupDevice.HardwareInfo = hardwareInfo;
                    }
                }

                // 检查是否已存在同名设备（在同一分组内）
                if (!string.IsNullOrEmpty(groupDevice.Name))
                {
                    var existingDevice = _collection.FindOne(x => x.Name == groupDevice.Name && x.GroupId == groupDevice.GroupId);
                    if (existingDevice != null)
                    {
                        return ApiResponse.Fail("插入失败: 该分组内已存在同名设备");
                    }
                }

                var id = _collection.Insert(groupDevice);
                return ApiResponse.Success(id.AsInt32, "插入成功");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("插入失败: " + ex.Message);
            }
        }

        // 仅用于插入一个临时设备
        public object InsertTemp(object param,int groupId)
        {
            try
            {
                var jsonString = param.ToString()!;
                var jObject = JObject.Parse(jsonString);

                // 创建新的GroupDevice对象
                var groupDevice = new GroupDevice();

                // 设置各个字段
                groupDevice.GroupId = groupId;
                
                if (jObject.TryGetValue("Name", out var nameToken))
                {
                    groupDevice.Name = nameToken.ToString();
                }
                if (jObject.TryGetValue("GatewayType", out var gatewayTypeToken))
                {
                    groupDevice.GatewayType = gatewayTypeToken.ToString();
                }
                if (jObject.TryGetValue("AllowDeviceRename", out var allowDeviceRenameToken))
                {
                    groupDevice.AllowDeviceRename = allowDeviceRenameToken.Value<bool>();
                }
                if (jObject.TryGetValue("AllowVariableRename", out var allowVariableRenameToken))
                {
                    groupDevice.AllowVariableRename = allowVariableRenameToken.Value<bool>();
                }
                if (jObject.TryGetValue("HardwareInfo", out var hardwareInfoToken))
                {
                    var hardwareInfo = hardwareInfoToken.ToObject<HardwareInfo>();
                    if (hardwareInfo != null)
                    {
                        groupDevice.HardwareInfo = hardwareInfo;
                    }
                }

                // 检查是否已存在同名设备（在同一分组内）
                if (!string.IsNullOrEmpty(groupDevice.Name))
                {
                    var existingDevice = _collection.FindOne(x => x.Name == groupDevice.Name && x.GroupId == groupDevice.GroupId);
                    if (existingDevice != null)
                    {
                        return ApiResponse.Fail("插入失败: 该分组内已存在同名设备");
                    }
                }

                var id = _collection.Insert(groupDevice);
                return ApiResponse.Success(id.AsInt32, "插入成功");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("插入失败: " + ex.Message);
            }
        }

        public object FindById(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                var result = _collection.FindById(id);
                if (result == null)
                    return ApiResponse.Fail("未找到数据", null, ApiResponseCode.NotFound);
                //将result转换为json字符串
                var resultJson = JsonConvert.SerializeObject(result);
                return ApiResponse.Success(resultJson);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }
        public object FindGroupById(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                var result = _collection.FindById(id);
                if (result == null)
                    return ApiResponse.Fail("未找到数据", null, ApiResponseCode.NotFound);
                //将result转换为json字符串
                var groupId = result.GroupId;
                return ApiResponse.Success(groupId);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }

        public object FindAll(object? param = null)
        {
            try
            {
                var list = _collection.FindAll().ToList();
                return ApiResponse.Success(list);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }

        public object Update(object param)
        {
            try
            {
                var jsonString = param.ToString()!;
                var jObject = JObject.Parse(jsonString);

                // 解析ID
                if (!jObject.TryGetValue("id", out var idToken) && !jObject.TryGetValue("Id", out idToken))
                {
                    return ApiResponse.Fail("更新失败: 缺少ID字段");
                }

                int id = idToken.Type == JTokenType.String ? 
                    int.Parse(idToken.ToString()) : 
                    idToken.Value<int>();

                // 获取现有记录
                var existingDevice = _collection.FindById(id);
                if (existingDevice == null)
                {
                    return ApiResponse.Fail("更新失败: 记录不存在");
                }

                // 更新字段
                if (jObject.TryGetValue("groupId", out var groupIdToken))
                {
                    existingDevice.GroupId = groupIdToken.Value<int>();
                }
                
                string newName = existingDevice.Name; // 保持原有名称作为默认值
                if (jObject.TryGetValue("name", out var nameToken))
                {
                    newName = nameToken.ToString();
                }
                
                if (jObject.TryGetValue("gatewayType", out var gatewayTypeToken))
                {
                    existingDevice.GatewayType = gatewayTypeToken.ToString();
                }
                if (jObject.TryGetValue("allowDeviceRename", out var allowDeviceRenameToken))
                {
                    existingDevice.AllowDeviceRename = allowDeviceRenameToken.Value<bool>();
                }
                if (jObject.TryGetValue("allowVariableRename", out var allowVariableRenameToken))
                {
                    existingDevice.AllowVariableRename = allowVariableRenameToken.Value<bool>();
                }
                if (jObject.TryGetValue("hardwareInfo", out var hardwareInfoToken))
                {
                    var hardwareInfo = hardwareInfoToken.ToObject<HardwareInfo>();
                    if (hardwareInfo != null)
                    {
                        existingDevice.HardwareInfo = hardwareInfo;
                    }
                }

                // 检查在同一分组内是否已存在同名设备（排除当前更新的记录）
                if (!string.IsNullOrEmpty(newName) && newName != existingDevice.Name)
                {
                    var duplicateDevice = _collection.FindOne(x => x.Name == newName && x.GroupId == existingDevice.GroupId && x.Id != id);
                    if (duplicateDevice != null)
                    {
                        return ApiResponse.Fail("更新失败: 该分组内已存在同名设备");
                    }
                }

                // 应用名称更新
                existingDevice.Name = newName;

                // 执行更新
                bool ok = _collection.Update(existingDevice);
                return ok ? ApiResponse.Success(ok, "更新成功") : ApiResponse.Fail("更新失败", ok);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("更新异常: " + ex.Message);
            }
        }

        public object Delete(object param)
        {
            try
            {
                int id = Convert.ToInt32(param);
                bool ok = _collection.Delete(id);
                return ok ? ApiResponse.Success(ok, "删除成功") : ApiResponse.Fail("删除失败", ok);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("删除异常: " + ex.Message);
            }
        }

        public object GetByGroupId(object param)
        {
            try
            {
                int groupId = Convert.ToInt32(param);
                var list = _collection.FindAll().Where(d => d.GroupId == groupId).ToList();
                return ApiResponse.Success(list);
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail("查询失败: " + ex.Message);
            }
        }
    }
}